home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / dviware / dvitovdu32 / src / pascal / screenio.p < prev    next >
Text File  |  1991-11-10  |  8KB  |  280 lines

  1. (* ScreenIO implements terminal i/o routines used by DVItoVDU.
  2.    Highly SYSDEP!
  3. *)
  4.  
  5. #include 'globals.h';
  6. #include 'screenio.h';
  7. #include 'unixio.h';
  8. #include 'vdu.h';
  9. (* IMPORT InitVDU, StartText, ClearScreen, ResetVDU.
  10.    To handle ^Z suspension properly, ScreenIO needs to use some VDU routines.
  11. *)
  12.  
  13. (* SYSDEP: We need to use the following Unix io routines.
  14.    In particular, using Pascal's write/writeln has some nasty side-effect
  15.    that prevents BusyRead from working!
  16. *)
  17.  
  18. FUNCTION getchar : integer;               EXTERNAL;
  19. FUNCTION putchar (ch : char) : integer;   EXTERNAL;
  20. FUNCTION write(f : integer; VAR b : screenbuf; n : integer) : integer; EXTERNAL;
  21.  
  22. (******************************************************************************)
  23.  
  24. PROCEDURE WriteChar (ch : CHAR);
  25.  
  26. (* This is the only place where a character is put into the output buffer.*)
  27.  
  28. VAR dummy : integer;
  29.  
  30. BEGIN
  31. IF buflen = maxbufsize THEN BEGIN
  32.    dummy := write(1,buf,buflen);   (* write entire buffer *)
  33.    buflen := 0;
  34. END;
  35. buf[buflen] := ch;
  36. buflen := buflen + 1;
  37. END; (* WriteChar *)
  38.  
  39. (******************************************************************************)
  40.  
  41. PROCEDURE WriteBuffer;
  42.  
  43. (* Output the buffer; either buffer is full or client has explicitly
  44.    requested the terminal to be updated.
  45. *)
  46.  
  47. VAR dummy : integer;
  48.  
  49. BEGIN
  50. IF buflen > 0 THEN BEGIN
  51.    dummy := write(1,buf,buflen);
  52.    buflen := 0;
  53. END;
  54. END; (* WriteBuffer *)
  55.  
  56. (******************************************************************************)
  57.  
  58. PROCEDURE WriteLine;
  59.  
  60. BEGIN
  61. WriteChar(CR);
  62. WriteBuffer;     (* WriteLine also updates terminal *)
  63. END; (* WriteLine *)
  64.  
  65. (******************************************************************************)
  66.  
  67. PROCEDURE WriteString (s: string);
  68.  
  69. (* This routine will not display trailing blanks. *)
  70.  
  71. LABEL 888;
  72.  
  73. VAR i, j : integer;
  74.  
  75. BEGIN
  76. j := maxstring;
  77. WHILE j > 0 DO BEGIN
  78.    j := j - 1;
  79.    IF s[j] <> ' ' THEN goto 888;
  80. END;
  81. 888:
  82. FOR i := 0 TO j DO WriteChar(s[i]);
  83. END; (* WriteString *)
  84.  
  85. (******************************************************************************)
  86.  
  87. PROCEDURE WriteCard (c : INTEGER);
  88.  
  89. (* Since the vast majority of given values will be small numbers, we avoid
  90.    recursion until c >= 100.
  91. *)
  92.  
  93. BEGIN
  94. IF c < 10 THEN
  95.    WriteChar( CHR(ORD('0') + c) )
  96. ELSE IF c < 100 THEN BEGIN
  97.    WriteChar( CHR(ORD('0') + (c DIV 10)) );
  98.    WriteChar( CHR(ORD('0') + (c MOD 10)) );
  99. END
  100. ELSE BEGIN
  101.    WriteCard(c DIV 100);   (* recursive if c >= 100 *)
  102.    c := c MOD 100;
  103.    WriteChar( CHR(ORD('0') + (c DIV 10)) );
  104.    WriteChar( CHR(ORD('0') + (c MOD 10)) );
  105. END;
  106. END; (* WriteCard *)
  107.  
  108. (******************************************************************************)
  109.  
  110. PROCEDURE WriteInt (i : INTEGER);
  111.  
  112. BEGIN
  113. IF i < 0 THEN BEGIN
  114.    WriteChar('-');
  115.    i := ABS(i);
  116. END;
  117. WriteCard(i);
  118. END; (* WriteInt *)
  119.  
  120. (******************************************************************************)
  121.  
  122. PROCEDURE RestoreTerminal;
  123.  
  124. (* RestoreTerminal should be called before any client module terminates. *)
  125.  
  126. BEGIN
  127. WriteBuffer;    (* make sure terminal is up-to-date *)
  128. restoretty;     (* restore terminal characteristics saved below *)
  129. END; (* RestoreTerminal *)
  130.  
  131. (******************************************************************************)
  132.  
  133. PROCEDURE ReadChar (VAR ch : CHAR);
  134.  
  135. VAR dummy : integer;
  136.  
  137. BEGIN
  138. (* assume singlecharon has been called *)
  139. ch := CHR(getchar);
  140. (* check for CTRLC or CTRLZ *)
  141. IF ch = CTRLC THEN BEGIN         (* interrupt *)
  142.    ch := CHR(getchar);           (* remove terminator *)
  143.    ch := CR;                     (* return to Command: level *)
  144. END
  145. ELSE IF ch = CTRLZ THEN BEGIN    (* suspend *)
  146.    ch := CHR(getchar);           (* remove terminator *)
  147.    StartText; ClearScreen; WriteLine; ResetVDU;
  148.    RestoreTerminal;
  149.    suspend;
  150.    savetty; singlecharon; echooff;
  151.    InitVDU; StartText;
  152.    ClearScreen;
  153.    ch := CR;                     (* return to Command: level *)
  154. END
  155. ELSE
  156.    dummy := putchar(ch);         (* echo ch since echooff has been called *)
  157. END; (* ReadChar *)
  158.  
  159. (******************************************************************************)
  160.  
  161. PROCEDURE ReadString (VAR s : string);
  162.  
  163. (* Read a string of characters.
  164.    The routine is terminated upon carriage return.
  165. *)
  166.  
  167. LABEL 888;
  168.  
  169. VAR ch : CHAR;   i : INTEGER;
  170.  
  171. BEGIN
  172. singlecharoff;                       (* read string in cooked mode *)
  173. echoon;                              (* echo characters *)
  174. s := ' ';                            (* init s with spaces *)
  175. i := 0;
  176. WHILE TRUE DO BEGIN
  177.    ch := CHR(getchar);
  178.    IF ch = CR THEN goto 888;
  179.    s[i] := ch;
  180.    IF i = maxstring THEN goto 888;
  181.    IF ch = CTRLC THEN BEGIN          (* interrupt *)
  182.       s := ' ';
  183.       goto 888;
  184.    END
  185.    ELSE IF ch = CTRLZ THEN BEGIN     (* suspend *)
  186.       StartText; ClearScreen; WriteLine; ResetVDU;
  187.       RestoreTerminal;
  188.       suspend;
  189.       savetty;
  190.       (* singlecharon and echooff are called below *)
  191.       InitVDU; StartText;
  192.       ClearScreen;
  193.       s := ' ';
  194.       goto 888;
  195.    END;
  196.    i := i + 1;
  197. END;
  198. 888:
  199. singlecharon;                        (* return to cbreak mode *)
  200. echooff;                             (* and no echo *)
  201. END; (* ReadString *)
  202.  
  203. (******************************************************************************)
  204.  
  205. FUNCTION BusyRead (VAR ch : CHAR) : BOOLEAN;
  206.  
  207. (* Return TRUE if ch is waiting in input buffer, and read it with no echo.
  208.    If nothing in input buffer then ch is undefined and we return FALSE.
  209. *)
  210.  
  211. BEGIN
  212. (* SYSDEP: buffercount assumes singlecharon and echooff have been called *)
  213. IF buffercount = 0 THEN
  214.    BusyRead := FALSE
  215. ELSE BEGIN
  216.    ch := CHR(getchar);
  217.    IF ch = CTRLC THEN BEGIN     (* interrupt *)
  218.       ch := CHR(getchar);       (* read terminator *)
  219.       ch := CR;                 (* main module will return to Command: level *)
  220.    END
  221.    ELSE IF ch = CTRLZ THEN BEGIN
  222.       (* suspend *)
  223.       ch := CHR(getchar);       (* read terminator *)
  224.       StartText; ClearScreen; WriteLine; ResetVDU;
  225.       RestoreTerminal;
  226.       suspend;
  227.       savetty; singlecharon; echooff;
  228.       InitVDU; StartText;
  229.       ClearScreen;
  230.       ch := CR;                 (* after suspend, return to Command: level *)
  231.    END;
  232.    BusyRead := TRUE;
  233. END;
  234. END; (* BusyRead *)
  235.  
  236. (******************************************************************************)
  237.  
  238. PROCEDURE InitTeXtoASCII;
  239.  
  240. (* Initialize TeXtoASCII array used in specific ShowChar/Rectangle routines
  241.    to map a given TeX char into a similar, displayable ASCII char.
  242. *)
  243.  
  244. VAR ch : CHAR;
  245.  
  246. BEGIN
  247. FOR ch :=  CHR( 0b) TO CHR( 12b) DO TeXtoASCII[ch] := '?'; (* Greek letters *)
  248. FOR ch :=  CHR(13b) TO CHR( 17b) DO TeXtoASCII[ch] := '?'; (* ligatures *)
  249. TeXtoASCII[CHR(20b)] := 'i';                               (* dotless i *)
  250. TeXtoASCII[CHR(21b)] := 'j';                               (* dotless j *)
  251. TeXtoASCII[CHR(22b)] := '`';                               (* grave accent *)
  252. TeXtoASCII[CHR(23b)] := '''';                              (* acute accent *)
  253. FOR ch :=  CHR(24b) TO CHR( 27b) DO TeXtoASCII[ch] := '~'; (* high accents *)
  254. TeXtoASCII[CHR(30b)] := ',';                               (* cedilla *)
  255. FOR ch :=  CHR(31b) TO CHR( 40b) DO TeXtoASCII[ch] := '?'; (* foreigns *)
  256. FOR ch :=  CHR(41b) TO CHR(133b) DO TeXtoASCII[ch] := ch ; (* same *)
  257. TeXtoASCII[CHR(134b)] := '"';                              (* open dble quote *)
  258. TeXtoASCII[CHR(135b)] := ']';                              (* same *)
  259. FOR ch := CHR(136b) TO CHR(137b) DO TeXtoASCII[ch] := '^'; (* more accents *)
  260. FOR ch := CHR(140b) TO CHR(172b) DO TeXtoASCII[ch] := ch ; (* same *)
  261. FOR ch := CHR(173b) TO CHR(174b) DO TeXtoASCII[ch] := '-'; (* en & em dash *)
  262. FOR ch := CHR(175b) TO CHR(177b) DO TeXtoASCII[ch] := '~'; (* more accents *)
  263. FOR ch := CHR(200b) TO CHR(377b) DO TeXtoASCII[ch] := '?';
  264. END; (* InitTeXtoASCII *)
  265.  
  266. (******************************************************************************)
  267.  
  268. PROCEDURE InitScreenIO;
  269.  
  270. BEGIN
  271. InitTeXtoASCII;
  272. buflen := 0;
  273. (* We first save the current terminal characteristics.
  274.    savetty also sets up ^C/^Z interrupt handlers; see unixio.c.
  275. *)
  276. savetty;
  277. singlecharon;   (* cbreak mode for ReadChar and BusyRead *)
  278. echooff;        (* no echo for BusyRead *)
  279. END; (* InitScreenIO *)
  280.